package org.youyun56.gpsserver.command;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.sql.SQLException;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.log4j.Logger;
import org.youyun56.gpsserver.Task;
import org.youyun56.gpsserver.common.DateUtils;
import org.youyun56.gpsserver.common.GoogleAddress;
import org.youyun56.gpsserver.common.GoogleStatus;
import org.youyun56.gpsserver.common.SessionKey;
import org.youyun56.gpsserver.entity.Car;
import org.youyun56.gpsserver.net.GpsServer;

import com.j3.sql.GridUtils;

public class UploadCarGpsLocationExecutor extends Task {
    private final static Logger logger = Logger.getLogger(UploadCarGpsLocationExecutor.class);

    @Override
    public Object execute() throws Exception {
        Car car = (Car) command.getSession().getAttribute(SessionKey.CAR);
        Long carId = null;
        if (car != null) {
            carId = car.getId();
        } else {
            carId = command.getParameters().getLong("carid");
        }
        if (carId != null) {
            String lat = command.getParameters().get("lat");
            String lng = command.getParameters().get("lng");
            if (lat != null && lat.length() > 0 && lng != null && lng.length() > 0) {
                findLocation(lat, lng, carId);
                return true;
            } else {
                return false;
            }
        }
        return false;
    }

    private void findLocation(String lat, String lng, Long carId) throws UnsupportedEncodingException, IOException {
        URL url = new URL(GpsServer.props
                .getProperty("latlngToLocationUrl",
                        "http://maps.google.com/maps/api/geocode/json?latlng=#X,#Y&sensor=false&language=zh-cn")
                .replace("#X", lat).replace("#Y", lng));
        StringBuffer html = null;
        InputStreamReader isr = new InputStreamReader(url.openStream(), "utf-8");
        BufferedReader br = new BufferedReader(isr);
        String lin = null;
        html = new StringBuffer();
        while ((lin = br.readLine()) != null) {
            html.append(lin);
        }
        isr.close();
        JSONObject o = JSONObject.fromObject(html.toString());
        // log.info(o);
        doMessage(o, html.toString(), lng, lat, carId);
    }

    public void doMessage(JSONObject o, String line, String x, String y, Long carId) {

        try {
            GoogleStatus status = GoogleStatus.valueOf(o.getString("status"));
            if (status == GoogleStatus.OK) {
                JSONArray array = o.getJSONArray("results");
                if (array.size() >= 3) {
                    JSONObject address = (JSONObject) array.get(0);
                    logger.info(address);
                    JSONArray addresses = address.getJSONArray("address_components");
                    int len = addresses.size();
                    StringBuffer local = new StringBuffer();
                    String city = null;
                    for (int i = len - 1; i >= 0; i--) {
                        JSONObject point = (JSONObject) addresses.get(i);
                        String longName = point.getString(GoogleAddress.long_name);
                        String type = (String) point.getJSONArray(GoogleAddress.types).get(0);
                        if (type.equals(GoogleAddress.locality)) {
                            city = longName;
                            local.append(longName);
                        } else if (type.equals(GoogleAddress.sublocality)) {
                            local.append(longName);
                            break;
                        } else if (type.equals(GoogleAddress.postal_code) || type.equals(GoogleAddress.country)) {
                            continue;
                        } else {
                            local.append(longName);
                        }
                    }
                    logger.info(String.format("City : %s ,LOCAL : %s", city, local));
                    GridUtils grid = new GridUtils();
                    grid.init("select id from city where name like '%" + city + "%'");
                    if (grid.next()) {
                        GridUtils
                                .update(String
                                        .format("update car set gps = 1,position = '%s' , lastPositionTime = '%s' , x = '%s' , y = '%s' , current_city = %d  where id = %d",
                                                local, DateUtils.getDateTime(), x, y, grid.getLong("id"), carId));

                    } else {
                        logger.error("City not Found: " + city);
                        GridUtils
                                .update(String
                                        .format("update car set gps = 1, position = '%s' , lastPositionTime = '%s' , x = '%s' , y = '%s'    where id = %d",
                                                local, DateUtils.getDateTime(), x, y, carId));
                    }

                }
            } else if (status == GoogleStatus.ZERO_RESULTS) {
                logger.error(line = " | " + GoogleStatus.OVER_QUERY_LIMIT.name());
            } else if (status == GoogleStatus.OVER_QUERY_LIMIT) {
                logger.error(line = " | " + GoogleStatus.OVER_QUERY_LIMIT.name());
            }
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            logger.error(e);
        }

    }

}
